home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / internet / other / mail / pathalia.zoo / src / parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-12  |  27.6 KB  |  1,052 lines

  1. #ifndef lint
  2. char yysccsid[] = "@(#)yaccpar    1.4 (Berkeley) 02/25/90";
  3. #endif
  4. #line 2 "parse.y"
  5. /* pathalias -- by steve bellovin, as told to peter honeyman */
  6. #ifndef lint
  7. static char    *sccsid = "@(#)parse.y    9.10 88/09/07";
  8. #endif /* lint */
  9.  
  10. #include "def.h"
  11.  
  12. /* scanner states (yylex, parse) */
  13. #define OTHER        0
  14. #define COSTING        1
  15. #define NEWLINE        2
  16. #define FILENAME    3
  17.  
  18. /* exports */
  19. long Tcount;
  20. extern void yyerror();
  21.  
  22. /* imports */
  23. extern node *addnode(), *addprivate();
  24. extern void fixprivate(), alias(), deadlink(), deletelink();
  25. extern link *addlink();
  26. extern int strcmp();
  27. extern char *strsave();
  28. extern int optind;
  29. extern char *Cfile, *Netchars, **Argv;
  30. extern int Lineno, Argc;
  31.  
  32. /* privates */
  33. STATIC void fixnet(), adjust();
  34. STATIC int yylex(), yywrap(), getword();
  35. static int Scanstate = NEWLINE;    /* scanner (yylex) state */
  36. int Donelast = 0;    /* we're all out of files to parse */
  37.  
  38. /* flags for ys_flags */
  39. #define TERMINAL 1
  40. #line 39 "parse.y"
  41. typedef union {
  42.     node    *y_node;
  43.     Cost    y_cost;
  44.     char    y_net;
  45.     char    *y_name;
  46.     struct {
  47.         node *ys_node;
  48.         Cost ys_cost;
  49.         short ys_flag;
  50.         char ys_net;
  51.         char ys_dir;
  52.     } y_s;
  53. } YYSTYPE;
  54. #line 55 "y_tab.c"
  55. #define SITE 257
  56. #define HOST 258
  57. #define STRING 259
  58. #define COST 260
  59. #define NET 261
  60. #define EOL 262
  61. #define PRIVATE 263
  62. #define DEAD 264
  63. #define DELETE 265
  64. #define FILETOK 266
  65. #define ADJUST 267
  66. #define YYERRCODE 256
  67. short yylhs[] = {                                        -1,
  68.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  69.     0,    3,    3,    3,    8,    8,    8,    8,    8,    8,
  70.     1,    1,    1,    2,    2,    4,    4,    4,    6,    6,
  71.     6,    9,    9,    7,    7,    7,   15,   15,    5,    5,
  72.     5,   16,   12,   12,   12,   11,   11,   10,   17,   20,
  73.    20,   20,   21,   21,   22,   23,   18,   19,   24,   24,
  74.    24,   25,   13,   26,   27,   13,   14,   14,   14,   14,
  75.    14,   14,   14,
  76. };
  77. short yylen[] = {                                         2,
  78.     0,    2,    3,    3,    3,    3,    3,    3,    3,    3,
  79.     2,    3,    4,    2,    1,    1,    1,    1,    1,    1,
  80.     1,    2,    2,    1,    3,    3,    3,    2,    5,    6,
  81.     6,    1,    2,    1,    3,    2,    4,    3,    1,    3,
  82.     2,    4,    1,    3,    2,    1,    3,    1,    4,    1,
  83.     3,    2,    1,    3,    0,    0,    6,    4,    1,    3,
  84.     2,    2,    0,    0,    0,    5,    1,    2,    3,    3,
  85.     3,    3,    3,
  86. };
  87. short yydefred[] = {                                      0,
  88.     0,    0,   11,   15,    2,    0,    0,    0,    0,    0,
  89.    32,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  90.     0,    0,    0,    0,   55,    0,    3,    0,    4,    0,
  91.     5,   24,    0,    0,    0,    0,    0,    0,    0,    6,
  92.     7,    8,    9,   10,   39,   38,    0,    0,    0,   43,
  93.     0,    0,    0,    0,   50,    0,   48,    0,    0,   59,
  94.     0,   27,   22,    0,   26,   64,   12,   23,    0,   34,
  95.     0,    0,   37,    0,    0,   42,    0,    0,   49,   56,
  96.    62,    0,   58,   13,   25,    0,    0,    0,    0,   40,
  97.    47,   44,   54,   51,    0,   60,   67,    0,    0,    0,
  98.     0,   35,    0,   29,   57,    0,    0,    0,    0,    0,
  99.     0,    0,   30,   31,   69,    0,    0,   72,   73,   66,
  100. };
  101. short yydgoto[] = {                                       2,
  102.    36,   37,   12,   13,   47,   14,   71,   15,   16,   49,
  103.    50,   51,   67,  100,   17,   18,   19,   20,   21,   54,
  104.    55,   56,   95,   59,   60,   86,  112,
  105. };
  106. short yysindex[] = {                                   -234,
  107.  -237,  -55,    0,    0,    0,  -96,  -93,  -78,  -74,  -72,
  108.     0,  -41,  -36, -204,  -44, -109, -202, -178, -177, -176,
  109.  -175, -104, -168, -167,    0, -166,    0,  -14,    0, -165,
  110.     0,    0,  -51, -164, -163,   59, -161,   -5, -154,    0,
  111.     0,    0,    0,    0,    0,    0,  -21,    0, -153,    0,
  112.   -20,    0, -150,  -18,    0, -142,    0,   59,  -16,    0,
  113.    59,    0,    0,   57,    0,    0,    0,    0, -154,    0,
  114.   -15, -137,    0, -166, -168,    0, -166, -167,    0,    0,
  115.     0, -166,    0,    0,    0,  -35,  -13, -135,  -38,    0,
  116.     0,    0,    0,    0,   -2,    0,    0,  -35,  -35,   14,
  117.    59,    0,   59,    0,    0,   28,   26,  -35,  -35,  -35,
  118.   -35,   83,    0,    0,    0,   28,   28,    0,    0,    0,
  119. };
  120. short yyrindex[] = {                                      1,
  121.     0,    0,    0,    0,    0,  -42,  -24,  -22,  -19,  -17,
  122.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  123.     0,    0,    0,    0,    0,    0,    0,  -33,    0,  -32,
  124.     0,    0,    0,    0, -103,  -31,  -40,    0,    0,    0,
  125.     0,    0,    0,    0,    0,    0,    0,  -37,    0,    0,
  126.     0,  -29,    0,    0,    0,    0,    0,  -12,    0,    0,
  127.   -31,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  128.     0,  -11,    0,    0,  -10,    0,    0,   -9,    0,    0,
  129.     0,   -4,    0,    0,    0,    0,    0,    3, -136,    0,
  130.     0,    0,    0,    0,    0,    0,    0,    0,    0,   84,
  131.  -136,    0, -136,    0,    0,   31,    0,    0,    0,    0,
  132.     0,    0,    0,    0,    0,   36,   37,    0,    0,    0,
  133. };
  134. short yygindex[] = {                                      0,
  135.    99,   96,    0,    0,    0,    0,   61,    0,    0,   24,
  136.    56,    0,   -6,  -45,    0,    0,    0,    0,    0,    0,
  137.    54,    0,    0,    0,   51,    0,    0,
  138. };
  139. #define YYTABLESIZE 268
  140. short yytable[] = {                                      21,
  141.     1,   66,   28,   21,   99,   11,   46,   30,   34,   98,
  142.    14,   28,   63,   39,   53,   34,   35,   16,   16,   33,
  143.    46,    1,   72,   75,    3,   78,   22,   82,   88,   23,
  144.    88,   63,   41,   45,   52,   17,   17,   18,   18,   61,
  145.    19,   19,   20,   20,   24,   34,   36,   53,   25,   58,
  146.    26,   81,  106,  107,   84,  110,  108,   31,  109,   40,
  147.   111,    1,  116,  117,  118,  119,  115,  110,  108,  110,
  148.   109,   68,  111,   68,  111,   68,   70,   71,   70,   71,
  149.    70,   71,  104,   41,   42,   43,   44,   46,   48,   52,
  150.    57,   62,   64,   65,  113,   53,  114,   91,   66,   68,
  151.    93,   53,   70,   73,   76,   58,   79,   74,   83,   89,
  152.    77,  101,   63,   41,   45,   52,   80,   69,   85,   90,
  153.    61,  102,  105,  120,   65,   63,   61,   36,   63,   87,
  154.    92,   94,   96,    0,    0,    0,    0,    0,    0,    0,
  155.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  156.     0,   38,   45,    0,    0,    0,    0,   33,    0,    0,
  157.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  158.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  159.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  160.     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
  161.     0,    0,    4,    0,    0,   32,    5,    6,    7,    8,
  162.     9,   10,   32,    0,   16,    0,   33,    0,   16,    0,
  163.    27,   21,  103,   48,   97,   29,    0,    0,   14,   28,
  164.    63,   48,   17,    0,   18,    0,   17,   19,   18,   20,
  165.     0,   19,   32,   20,    0,    0,   33,    0,    0,    0,
  166.     0,    0,    0,    0,    0,    0,    0,    0,    1,    0,
  167.     0,    0,    1,    1,    1,    1,    1,    1,
  168. };
  169. short yycheck[] = {                                      40,
  170.     0,   40,   44,   44,   40,   61,   44,   44,   60,   45,
  171.    44,   44,   44,  123,   44,   60,   61,   60,   61,  123,
  172.   125,  256,   44,   44,  262,   44,  123,   44,   44,  123,
  173.    44,   44,   44,   44,   44,   60,   61,   60,   61,   44,
  174.    60,   61,   60,   61,  123,   60,   44,   24,  123,   26,
  175.   123,   58,   98,   99,   61,   42,   43,  262,   45,  262,
  176.    47,   61,  108,  109,  110,  111,   41,   42,   43,   42,
  177.    45,   41,   47,   43,   47,   45,   41,   41,   43,   43,
  178.    45,   45,   89,  262,  262,  262,  262,  125,  257,  257,
  179.   257,  257,  257,  257,  101,  125,  103,   74,   40,  261,
  180.    77,   78,  257,  125,  125,   82,  125,  261,  125,  125,
  181.   261,  125,  125,  125,  125,  125,  259,  123,   62,  257,
  182.   125,  257,  125,   41,   41,  262,   28,  125,   33,   69,
  183.    75,   78,   82,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  184.    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  185.    -1,  261,  257,   -1,   -1,   -1,   -1,  261,   -1,   -1,
  186.    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  187.    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  188.    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  189.    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
  190.    -1,   -1,  258,   -1,   -1,  257,  262,  263,  264,  265,
  191.   266,  267,  257,   -1,  257,   -1,  261,   -1,  261,   -1,
  192.   262,  262,  261,  261,  260,  262,   -1,   -1,  262,  262,
  193.   262,  261,  257,   -1,  257,   -1,  261,  257,  261,  257,
  194.    -1,  261,  257,  261,   -1,   -1,  261,   -1,   -1,   -1,
  195.    -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  258,   -1,
  196.    -1,   -1,  262,  263,  264,  265,  266,  267,
  197. };
  198. #define YYFINAL 2
  199. #ifndef YYDEBUG
  200. #define YYDEBUG 0
  201. #endif
  202. #define YYMAXTOKEN 267
  203. #if YYDEBUG
  204. char *yyname[] = {
  205. "end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  206. 0,0,0,0,0,0,"'('","')'","'*'","'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,0,0,
  207. "'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  208. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,
  209. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  210. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  211. 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  212. 0,0,0,0,0,0,0,"SITE","HOST","STRING","COST","NET","EOL","PRIVATE","DEAD",
  213. "DELETE","FILETOK","ADJUST",
  214. };
  215. char *yyrule[] = {
  216. "$accept : map",
  217. "map :",
  218. "map : map EOL",
  219. "map : map links EOL",
  220. "map : map aliases EOL",
  221. "map : map network EOL",
  222. "map : map private EOL",
  223. "map : map dead EOL",
  224. "map : map delete EOL",
  225. "map : map file EOL",
  226. "map : map adjust EOL",
  227. "map : error EOL",
  228. "links : host site cost",
  229. "links : links ',' site cost",
  230. "links : links ','",
  231. "host : HOST",
  232. "host : PRIVATE",
  233. "host : DEAD",
  234. "host : DELETE",
  235. "host : FILETOK",
  236. "host : ADJUST",
  237. "site : asite",
  238. "site : NET asite",
  239. "site : asite NET",
  240. "asite : SITE",
  241. "asite : '<' SITE '>'",
  242. "aliases : host '=' SITE",
  243. "aliases : aliases ',' SITE",
  244. "aliases : aliases ','",
  245. "network : nhost '{' nlist '}' cost",
  246. "network : nhost NET '{' nlist '}' cost",
  247. "network : nhost '{' nlist '}' NET cost",
  248. "nhost : '='",
  249. "nhost : host '='",
  250. "nlist : SITE",
  251. "nlist : nlist ',' SITE",
  252. "nlist : nlist ','",
  253. "private : PRIVATE '{' plist '}'",
  254. "private : PRIVATE '{' '}'",
  255. "plist : SITE",
  256. "plist : plist ',' SITE",
  257. "plist : plist ','",
  258. "dead : DEAD '{' dlist '}'",
  259. "dlist : delem",
  260. "dlist : dlist ',' delem",
  261. "dlist : dlist ','",
  262. "delem : SITE",
  263. "delem : usite NET usite",
  264. "usite : SITE",
  265. "delete : DELETE '{' dellist '}'",
  266. "dellist : delelem",
  267. "dellist : dellist ',' delelem",
  268. "dellist : dellist ','",
  269. "delelem : SITE",
  270. "delelem : usite NET usite",
  271. "$$1 :",
  272. "$$2 :",
  273. "file : FILETOK '{' $$1 STRING $$2 '}'",
  274. "adjust : ADJUST '{' adjlist '}'",
  275. "adjlist : adjelem",
  276. "adjlist : adjlist ',' adjelem",
  277. "adjlist : adjlist ','",
  278. "adjelem : usite cost",
  279. "cost :",
  280. "$$3 :",
  281. "$$4 :",
  282. "cost : '(' $$3 cexpr $$4 ')'",
  283. "cexpr : COST",
  284. "cexpr : '-' cexpr",
  285. "cexpr : '(' cexpr ')'",
  286. "cexpr : cexpr '+' cexpr",
  287. "cexpr : cexpr '-' cexpr",
  288. "cexpr : cexpr '*' cexpr",
  289. "cexpr : cexpr '/' cexpr",
  290. };
  291. #endif
  292. #define yyclearin (yychar=(-1))
  293. #define yyerrok (yyerrflag=0)
  294. #ifndef YYSTACKSIZE
  295. #ifdef YYMAXDEPTH
  296. #define YYSTACKSIZE YYMAXDEPTH
  297. #else
  298. #define YYSTACKSIZE 300
  299. #endif
  300. #endif
  301. int yydebug;
  302. int yynerrs;
  303. int yyerrflag;
  304. int yychar;
  305. short *yyssp;
  306. YYSTYPE *yyvsp;
  307. YYSTYPE yyval;
  308. YYSTYPE yylval;
  309. #define yystacksize YYSTACKSIZE
  310. short yyss[YYSTACKSIZE];
  311. YYSTYPE yyvs[YYSTACKSIZE];
  312. #line 236 "parse.y"
  313.  
  314. void
  315. #ifdef YYDEBUG
  316. /*VARARGS1*/
  317. yyerror(fmt, arg)
  318.     char *fmt, *arg;
  319. #else
  320. yyerror(s)
  321.     char *s;
  322. #endif
  323. {
  324.     /* a concession to bsd error(1) */
  325.     fprintf(stderr, "\"%s\", ", Cfile);
  326. #ifdef YYDEBUG
  327.     fprintf(stderr, "line %d: ", Lineno);
  328.     fprintf(stderr, fmt, arg);
  329.     putc('\n', stderr);
  330. #else
  331.     fprintf(stderr, "line %d: %s\n", Lineno, s);
  332. #endif
  333. }
  334.  
  335. /*
  336.  * patch in the costs of getting on/off the network.
  337.  *
  338.  * for each network member on netlist, add links:
  339.  *    network -> member    cost = 0;
  340.  *    member -> network    cost = parameter.
  341.  *
  342.  * if network and member both require gateways, assume network
  343.  * is a gateway to member (but not v.v., to avoid such travesties
  344.  * as topaz!seismo.css.gov.edu.rutgers).
  345.  *
  346.  * note that members can have varying costs to a network, by suitable
  347.  * multiple declarations.  this is a feechur, albeit a useless one.
  348.  */
  349. STATIC void
  350. fixnet(network, nlist, cost, netchar, netdir)
  351.     register node *network;
  352.     node *nlist;
  353.     Cost cost;
  354.     char netchar, netdir;
  355. {    register node *member, *nextnet;
  356.     link *l;
  357.     static int netanon = 0;
  358.     char anon[25];
  359.  
  360.     if (network == 0) {
  361.         sprintf(anon, "[unnamed net %d]", netanon++);
  362.         network = addnode(anon);
  363.     }
  364.     network->n_flag |= NNET;
  365.  
  366.     /* insert the links */
  367.     for (member = nlist ; member; member = nextnet) {
  368.  
  369.         /* network -> member, cost is 0 */
  370.         l = addlink(network, member, (Cost) 0, netchar, netdir);
  371.         if (GATEWAYED(network) && GATEWAYED(member))
  372.             l->l_flag |= LGATEWAY;
  373.  
  374.         /* member -> network, cost is parameter */
  375.         /* never ever ever crawl up from a domain*/
  376.         if (!ISADOMAIN(network))
  377.             (void) addlink(member, network, cost, netchar, netdir);
  378.  
  379.         nextnet = member->n_net;
  380.         member->n_net = 0;    /* clear for later use */
  381.     }
  382. }
  383.  
  384. /* scanner */
  385.  
  386. #define QUOTE '"'
  387. #define STR_EQ(s1, s2) (s1[2] == s2[2] && strcmp(s1, s2) == 0)
  388. #define NLRETURN() {Scanstate = NEWLINE; return EOL;}
  389.  
  390. static struct ctable {
  391.     char *cname;
  392.     Cost cval;
  393. } ctable[] = {
  394.     /* ordered by frequency of appearance in a "typical" dataset */
  395.     {"DIRECT", 200},
  396.     {"DEMAND", 300},
  397.     {"DAILY", 5000},
  398.     {"HOURLY", 500},
  399.     {"DEDICATED", 100},
  400.     {"EVENING", 2000},
  401.     {"LOCAL", 25},
  402.     {"LOW", 5},    /* baud rate, quality penalty */
  403.     {"DEAD", MILLION},
  404.     {"POLLED", 5000},
  405.     {"WEEKLY", 30000},
  406.     {"HIGH", -5},    /* baud rate, quality bonus */
  407.     {"FAST", -80},    /* high speed (>= 9.6 kbps) modem */
  408.     /* deprecated */
  409.     {"ARPA", 100},
  410.     {"DIALED", 300},
  411.     {0, 0}
  412. };
  413.  
  414. STATIC int
  415. yylex()
  416. {    static char retbuf[128];    /* for return to yacc part */
  417.     register int c;
  418.     register char *buf = retbuf;
  419.     register struct ctable *ct;
  420.     register Cost cost;
  421.     char errbuf[128];
  422.     
  423.     if( Donelast == -1 && yywrap() )
  424.         return EOF;
  425.  
  426.     if (Donelast || feof(stdin) && yywrap())
  427.         return EOF;
  428.  
  429.     /* count lines, skip over space and comments */
  430.     if ((c = getchar()) == EOF)
  431.         NLRETURN();
  432.     
  433. continuation:
  434.     while (c == ' ' || c == '\t')
  435.         if ((c = getchar()) == EOF)
  436.             NLRETURN();
  437.  
  438.     if (c == '#')
  439.         while ((c = getchar()) != '\n')
  440.             if (c == EOF)
  441.                 NLRETURN();
  442.  
  443.     /* scan token */
  444.     if (c == '\n') {
  445.         Lineno++;
  446.         if ((c = getchar()) != EOF) {
  447.             if (c == ' ' || c == '\t')
  448.                 goto continuation;
  449.             ungetc(c, stdin);
  450.         }
  451.         NLRETURN();
  452.     }
  453.  
  454.     switch(Scanstate) {
  455.     case COSTING:
  456.         if (isdigit(c)) {
  457.             cost = c - '0';
  458.             for (c = getchar(); isdigit(c); c = getchar())
  459.                 cost = (cost * 10) + c - '0';
  460.             ungetc(c, stdin);
  461.             yylval.y_cost = cost;
  462.             return COST;
  463.         }
  464.  
  465.         if (getword(buf, c) == 0) {
  466.             for (ct = ctable; ct->cname; ct++)
  467.                 if (STR_EQ(buf, ct->cname)) {
  468.                     yylval.y_cost = ct->cval;
  469.                     return COST;
  470.                 }
  471.             sprintf(errbuf, "unknown cost (%s), using default", buf);
  472.             yyerror(errbuf);
  473.             yylval.y_cost = DEFCOST;
  474.             return COST;
  475.         }
  476.  
  477.         return c;    /* pass the buck */
  478.  
  479.     case NEWLINE:
  480.         Scanstate = OTHER;
  481.         if (getword(buf, c) != 0)
  482.             return c;
  483.         /*
  484.          * special purpose tokens.
  485.          *
  486.          * the "switch" serves the dual-purpose of recognizing
  487.          * unquoted tokens only.
  488.          */
  489.         switch(c) {
  490.         case 'p':
  491.             if (STR_EQ(buf, "private"))
  492.                 return PRIVATE;
  493.             break;
  494.         case 'd':
  495.             if (STR_EQ(buf, "dead"))
  496.                 return DEAD;
  497.             if (STR_EQ(buf, "delete"))
  498.                 return DELETE;
  499.             break;
  500.         case 'f':
  501.             if (STR_EQ(buf, "file"))
  502.                 return FILETOK;
  503.             break;
  504.         case 'a':
  505.             if (STR_EQ(buf, "adjust"))
  506.                 return ADJUST;
  507.             break;
  508.         }
  509.  
  510.         yylval.y_name = buf;
  511.         return HOST;
  512.  
  513.     case FILENAME:
  514.         while (c != EOF && isprint(c)) {
  515.             if (c == ' ' || c == '\t' || c == '\n' || c == '}')
  516.                 break;
  517.             *buf++ = c;
  518.             c = getchar();
  519.         }
  520.         if (c != EOF)
  521.             ungetc(c, stdin);
  522.         *buf = 0;
  523.         yylval.y_name = retbuf;
  524.         return STRING;
  525.     }
  526.  
  527.     if (getword(buf, c) == 0) {
  528.         yylval.y_name = buf;
  529.         return SITE;
  530.     }
  531.  
  532.     if (index(Netchars, c)) {
  533.         yylval.y_net = c;
  534.         return NET;
  535.     }
  536.  
  537.     return c;
  538. }
  539.  
  540. /*
  541.  * fill str with the next word in [0-9A-Za-z][-._0-9A-Za-z]+ or a quoted
  542.  * string that contains no newline.  return -1 on failure or EOF, 0 o.w.
  543.  */ 
  544. STATIC int
  545. getword(str, c)
  546.     register char *str;
  547.     register int c;
  548. {
  549.     if (c == QUOTE) {
  550.         while ((c = getchar()) != QUOTE) {
  551.             if (c == '\n') {
  552.                 yyerror("newline in quoted string\n");
  553.                 ungetc(c, stdin);
  554.                 return -1;
  555.             }
  556.             if (c == EOF) {
  557.                 yyerror("EOF in quoted string\n");
  558.                 return -1;
  559.             }
  560.             *str++ = c;
  561.         }
  562.         *str = 0;
  563.         return 0;
  564.     }
  565.  
  566.     /* host name must start with alphanumeric or `.' */
  567.     if (!isalnum(c) && c != '.')
  568.         return -1;
  569.  
  570. yymore:
  571.     do {
  572.         *str++ = c;
  573.         c = getchar();
  574.     } while (isalnum(c) || c == '.' || c == '_');
  575.  
  576.     if (c == '-' && Scanstate != COSTING)
  577.         goto yymore;
  578.  
  579.     ungetc(c, stdin);
  580.     *str = 0;
  581.     return 0;
  582. }
  583.  
  584. STATIC int
  585. yywrap()
  586. {    char errbuf[100];
  587.  
  588.     fixprivate();    /* munge private host definitions */
  589.     Lineno = 1;
  590.     Donelast = 0;        /* we're not at the end of the list */
  591.     while (optind < Argc) {
  592.         if (freopen((Cfile = Argv[optind++]), "r", stdin) != 0)
  593.             return 0;
  594.         sprintf(errbuf, "%s: %s", Argv[0], Cfile);
  595.         perror(errbuf);
  596.     }
  597.     /* freopen(NULL_FILE, "r", stdin); */
  598.     Donelast=1;    /* so maybe we are, sue me */
  599.     return -1;
  600. }
  601.  
  602. STATIC void
  603. adjust(n, cost)
  604.     node *n;
  605.     Cost cost;
  606. {    link *l;
  607.  
  608.     n->n_cost += cost;    /* cumulative */
  609.  
  610.     /* hit existing links */
  611.     for (l = n->n_link; l; l = l->l_next) {
  612.         if ((l->l_cost += cost) < 0) {
  613.             char buf[100];
  614.  
  615.             l->l_flag |= LDEAD;
  616.             sprintf(buf, "link to %s deleted with negative cost",
  617.                             l->l_to->n_name);
  618.             yyerror(buf);
  619.         }
  620.     }
  621. }
  622. #line 623 "y_tab.c"
  623. #define YYABORT goto yyabort
  624. #define YYACCEPT goto yyaccept
  625. #define YYERROR goto yyerrlab
  626. int
  627. yyparse()
  628. {
  629.     register int yym, yyn, yystate;
  630. #if YYDEBUG
  631.     register char *yys;
  632.     extern char *getenv();
  633.  
  634.     if (yys = getenv("YYDEBUG"))
  635.     {
  636.         yyn = *yys;
  637.         if (yyn >= '0' && yyn <= '9')
  638.             yydebug = yyn - '0';
  639.     }
  640. #endif
  641.  
  642.     yynerrs = 0;
  643.     yyerrflag = 0;
  644.     yychar = (-1);
  645.  
  646.     yyssp = yyss;
  647.     yyvsp = yyvs;
  648.     *yyssp = yystate = 0;
  649.  
  650. yyloop:
  651.     if (yyn = yydefred[yystate]) goto yyreduce;
  652.     if (yychar < 0)
  653.     {
  654.         if ((yychar = yylex()) < 0) yychar = 0;
  655. #if YYDEBUG
  656.         if (yydebug)
  657.         {
  658.             yys = 0;
  659.             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  660.             if (!yys) yys = "illegal-symbol";
  661.             printf("yydebug: state %d, reading %d (%s)\n", yystate,
  662.                     yychar, yys);
  663.         }
  664. #endif
  665.     }
  666.     if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
  667.             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
  668.     {
  669. #if YYDEBUG
  670.         if (yydebug)
  671.             printf("yydebug: state %d, shifting to state %d\n",
  672.                     yystate, yytable[yyn]);
  673. #endif
  674.         if (yyssp >= yyss + yystacksize - 1)
  675.         {
  676.             goto yyoverflow;
  677.         }
  678.         *++yyssp = yystate = yytable[yyn];
  679.         *++yyvsp = yylval;
  680.         yychar = (-1);
  681.         if (yyerrflag > 0)  --yyerrflag;
  682.         goto yyloop;
  683.     }
  684.     if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
  685.             yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
  686.     {
  687.         yyn = yytable[yyn];
  688.         goto yyreduce;
  689.     }
  690.     if (yyerrflag) goto yyinrecovery;
  691. #ifdef lint
  692.     goto yynewerror;
  693. #endif
  694. yynewerror:
  695.     yyerror("syntax error");
  696. #ifdef lint
  697.     goto yyerrlab;
  698. #endif
  699. yyerrlab:
  700.     ++yynerrs;
  701. yyinrecovery:
  702.     if (yyerrflag < 3)
  703.     {
  704.         yyerrflag = 3;
  705.         for (;;)
  706.         {
  707.             if ((yyn = yysindex[*yyssp]) && (yyn += YYERRCODE) >= 0 &&
  708.                     yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
  709.             {
  710. #if YYDEBUG
  711.                 if (yydebug)
  712.                     printf("yydebug: state %d, error recovery shifting\
  713.  to state %d\n", *yyssp, yytable[yyn]);
  714. #endif
  715.                 if (yyssp >= yyss + yystacksize - 1)
  716.                 {
  717.                     goto yyoverflow;
  718.                 }
  719.                 *++yyssp = yystate = yytable[yyn];
  720.                 *++yyvsp = yylval;
  721.                 goto yyloop;
  722.             }
  723.             else
  724.             {
  725. #if YYDEBUG
  726.                 if (yydebug)
  727.                     printf("yydebug: error recovery discarding state %d\n",
  728.                             *yyssp);
  729. #endif
  730.                 if (yyssp <= yyss) goto yyabort;
  731.                 --yyssp;
  732.                 --yyvsp;
  733.             }
  734.         }
  735.     }
  736.     else
  737.     {
  738.         if (yychar == 0) goto yyabort;
  739. #if YYDEBUG
  740.         if (yydebug)
  741.         {
  742.             yys = 0;
  743.             if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  744.             if (!yys) yys = "illegal-symbol";
  745.             printf("yydebug: state %d, error recovery discards token %d (%s)\n",
  746.                     yystate, yychar, yys);
  747.         }
  748. #endif
  749.         yychar = (-1);
  750.         goto yyloop;
  751.     }
  752. yyreduce:
  753. #if YYDEBUG
  754.     if (yydebug)
  755.         printf("yydebug: state %d, reducing by rule %d (%s)\n",
  756.                 yystate, yyn, yyrule[yyn]);
  757. #endif
  758.     yym = yylen[yyn];
  759.     yyval = yyvsp[1-yym];
  760.     switch (yyn)
  761.     {
  762. case 12:
  763. #line 80 "parse.y"
  764. {
  765.         struct link *l;
  766.  
  767.         l = addlink(yyvsp[-2].y_node , yyvsp[-1].y_s .ys_node, yyvsp[0].y_cost , yyvsp[-1].y_s .ys_net, yyvsp[-1].y_s .ys_dir);
  768.         if (GATEWAYED(yyvsp[-1].y_s .ys_node))
  769.             l->l_flag |= LGATEWAY;
  770.         if (yyvsp[-1].y_s .ys_flag & TERMINAL)
  771.             l->l_flag |= LTERMINAL;
  772.       }
  773. break;
  774. case 13:
  775. #line 89 "parse.y"
  776. {
  777.         struct link *l;
  778.  
  779.         l = addlink(yyvsp[-3].y_node , yyvsp[-1].y_s .ys_node, yyvsp[0].y_cost , yyvsp[-1].y_s .ys_net, yyvsp[-1].y_s .ys_dir);
  780.         if (GATEWAYED(yyvsp[-1].y_s .ys_node))
  781.             l->l_flag |= LGATEWAY;
  782.         if (yyvsp[-1].y_s .ys_flag & TERMINAL)
  783.             l->l_flag |= LTERMINAL;
  784.       }
  785. break;
  786. case 15:
  787. #line 101 "parse.y"
  788. {yyval.y_node  = addnode(yyvsp[0].y_name );}
  789. break;
  790. case 16:
  791. #line 102 "parse.y"
  792. {yyval.y_node  = addnode("private");}
  793. break;
  794. case 17:
  795. #line 103 "parse.y"
  796. {yyval.y_node  = addnode("dead");}
  797. break;
  798. case 18:
  799. #line 104 "parse.y"
  800. {yyval.y_node  = addnode("delete");}
  801. break;
  802. case 19:
  803. #line 105 "parse.y"
  804. {yyval.y_node  = addnode("file");}
  805. break;
  806. case 20:
  807. #line 106 "parse.y"
  808. {yyval.y_node  = addnode("adjust");}
  809. break;
  810. case 21:
  811. #line 109 "parse.y"
  812. {
  813.         yyval.y_s  = yyvsp[0].y_s ;
  814.         yyval.y_s .ys_net = DEFNET;
  815.         yyval.y_s .ys_dir = DEFDIR;
  816.       }
  817. break;
  818. case 22:
  819. #line 114 "parse.y"
  820. {
  821.         yyval.y_s  = yyvsp[0].y_s ;
  822.         yyval.y_s .ys_net = yyvsp[-1].y_net ;
  823.         yyval.y_s .ys_dir = LRIGHT;
  824.       }
  825. break;
  826. case 23:
  827. #line 119 "parse.y"
  828. {
  829.         yyval.y_s  = yyvsp[-1].y_s ;
  830.         yyval.y_s .ys_net = yyvsp[0].y_net ;
  831.         yyval.y_s .ys_dir = LLEFT;
  832.       }
  833. break;
  834. case 24:
  835. #line 126 "parse.y"
  836. {
  837.         yyval.y_s .ys_node = addnode(yyvsp[0].y_name );
  838.         yyval.y_s .ys_flag = 0;
  839.       }
  840. break;
  841. case 25:
  842. #line 130 "parse.y"
  843. {
  844.         Tcount++;
  845.         yyval.y_s .ys_node = addnode(yyvsp[-1].y_name );
  846.         yyval.y_s .ys_flag = TERMINAL;
  847.       }
  848. break;
  849. case 26:
  850. #line 137 "parse.y"
  851. {alias(yyvsp[-2].y_node , addnode(yyvsp[0].y_name ));}
  852. break;
  853. case 27:
  854. #line 138 "parse.y"
  855. {alias(yyvsp[-2].y_node , addnode(yyvsp[0].y_name ));}
  856. break;
  857. case 29:
  858. #line 142 "parse.y"
  859. {fixnet(yyvsp[-4].y_node , yyvsp[-2].y_node , yyvsp[0].y_cost , DEFNET, DEFDIR);}
  860. break;
  861. case 30:
  862. #line 143 "parse.y"
  863. {fixnet(yyvsp[-5].y_node , yyvsp[-2].y_node , yyvsp[0].y_cost , yyvsp[-4].y_net , LRIGHT);}
  864. break;
  865. case 31:
  866. #line 144 "parse.y"
  867. {fixnet(yyvsp[-5].y_node , yyvsp[-3].y_node , yyvsp[0].y_cost , yyvsp[-1].y_net , LLEFT);}
  868. break;
  869. case 32:
  870. #line 147 "parse.y"
  871. {yyval.y_node  = 0;    /* anonymous net */}
  872. break;
  873. case 33:
  874. #line 148 "parse.y"
  875. {yyval.y_node  = yyvsp[-1].y_node ;    /* named net */}
  876. break;
  877. case 34:
  878. #line 151 "parse.y"
  879. {yyval.y_node  = addnode(yyvsp[0].y_name );}
  880. break;
  881. case 35:
  882. #line 152 "parse.y"
  883. {
  884.         node *n;
  885.  
  886.         n = addnode(yyvsp[0].y_name );
  887.         if (n->n_net == 0) {
  888.             n->n_net = yyvsp[-2].y_node ;
  889.             yyval.y_node  = n;
  890.         }
  891.       }
  892. break;
  893. case 38:
  894. #line 165 "parse.y"
  895. {fixprivate();}
  896. break;
  897. case 39:
  898. #line 168 "parse.y"
  899. {addprivate(yyvsp[0].y_name )->n_flag |= ISPRIVATE;}
  900. break;
  901. case 40:
  902. #line 169 "parse.y"
  903. {addprivate(yyvsp[0].y_name )->n_flag |= ISPRIVATE;}
  904. break;
  905. case 46:
  906. #line 180 "parse.y"
  907. {deadlink(addnode(yyvsp[0].y_name ), (node *) 0);}
  908. break;
  909. case 47:
  910. #line 181 "parse.y"
  911. {deadlink(yyvsp[-2].y_node , yyvsp[0].y_node );}
  912. break;
  913. case 48:
  914. #line 184 "parse.y"
  915. {yyval.y_node  = addnode(yyvsp[0].y_name );}
  916. break;
  917. case 53:
  918. #line 193 "parse.y"
  919. {
  920.         node *n;
  921.  
  922.         n = addnode(yyvsp[0].y_name );
  923.         deletelink(n, (node *) 0);
  924.         n->n_flag |= ISPRIVATE;
  925.       }
  926. break;
  927. case 54:
  928. #line 200 "parse.y"
  929. {deletelink(yyvsp[-2].y_node , yyvsp[0].y_node );}
  930. break;
  931. case 55:
  932. #line 203 "parse.y"
  933. {Scanstate = FILENAME;}
  934. break;
  935. case 56:
  936. #line 203 "parse.y"
  937. {Scanstate = OTHER;}
  938. break;
  939. case 57:
  940. #line 203 "parse.y"
  941. {
  942.         Lineno = 0;
  943.         Cfile = strsave(yyvsp[-2].y_name );
  944.     }
  945. break;
  946. case 62:
  947. #line 215 "parse.y"
  948. {adjust(yyvsp[-1].y_node , yyvsp[0].y_cost );}
  949. break;
  950. case 63:
  951. #line 217 "parse.y"
  952. {yyval.y_cost  = DEFCOST;    /* empty -- cost is always optional */}
  953. break;
  954. case 64:
  955. #line 218 "parse.y"
  956. {Scanstate = COSTING;}
  957. break;
  958. case 65:
  959. #line 218 "parse.y"
  960. {Scanstate = OTHER;}
  961. break;
  962. case 66:
  963. #line 219 "parse.y"
  964. {yyval.y_cost  = yyvsp[-2].y_cost ;}
  965. break;
  966. case 68:
  967. #line 223 "parse.y"
  968. {yyval.y_cost  = -yyvsp[0].y_cost ;}
  969. break;
  970. case 69:
  971. #line 224 "parse.y"
  972. {yyval.y_cost  = yyvsp[-1].y_cost ;}
  973. break;
  974. case 70:
  975. #line 225 "parse.y"
  976. {yyval.y_cost  = yyvsp[-2].y_cost  + yyvsp[0].y_cost ;}
  977. break;
  978. case 71:
  979. #line 226 "parse.y"
  980. {yyval.y_cost  = yyvsp[-2].y_cost  - yyvsp[0].y_cost ;}
  981. break;
  982. case 72:
  983. #line 227 "parse.y"
  984. {yyval.y_cost  = yyvsp[-2].y_cost  * yyvsp[0].y_cost ;}
  985. break;
  986. case 73:
  987. #line 228 "parse.y"
  988. {
  989.         if (yyvsp[0].y_cost  == 0)
  990.             yyerror("zero divisor\n");
  991.         else
  992.             yyval.y_cost  = yyvsp[-2].y_cost  / yyvsp[0].y_cost ;
  993.       }
  994. break;
  995. #line 996 "y_tab.c"
  996.     }
  997.     yyssp -= yym;
  998.     yystate = *yyssp;
  999.     yyvsp -= yym;
  1000.     yym = yylhs[yyn];
  1001.     if (yystate == 0 && yym == 0)
  1002.     {
  1003. #ifdef YYDEBUG
  1004.         if (yydebug)
  1005.             printf("yydebug: after reduction, shifting from state 0 to\
  1006.  state %d\n", YYFINAL);
  1007. #endif
  1008.         yystate = YYFINAL;
  1009.         *++yyssp = YYFINAL;
  1010.         *++yyvsp = yyval;
  1011.         if (yychar < 0)
  1012.         {
  1013.             if ((yychar = yylex()) < 0) yychar = 0;
  1014. #if YYDEBUG
  1015.             if (yydebug)
  1016.             {
  1017.                 yys = 0;
  1018.                 if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
  1019.                 if (!yys) yys = "illegal-symbol";
  1020.                 printf("yydebug: state %d, reading %d (%s)\n",
  1021.                         YYFINAL, yychar, yys);
  1022.             }
  1023. #endif
  1024.         }
  1025.         if (yychar == 0) goto yyaccept;
  1026.         goto yyloop;
  1027.     }
  1028.     if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
  1029.             yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
  1030.         yystate = yytable[yyn];
  1031.     else
  1032.         yystate = yydgoto[yym];
  1033. #ifdef YYDEBUG
  1034.     if (yydebug)
  1035.         printf("yydebug: after reduction, shifting from state %d \
  1036. to state %d\n", *yyssp, yystate);
  1037. #endif
  1038.     if (yyssp >= yyss + yystacksize - 1)
  1039.     {
  1040.         goto yyoverflow;
  1041.     }
  1042.     *++yyssp = yystate;
  1043.     *++yyvsp = yyval;
  1044.     goto yyloop;
  1045. yyoverflow:
  1046.     yyerror("yacc stack overflow");
  1047. yyabort:
  1048.     return (1);
  1049. yyaccept:
  1050.     return (0);
  1051. }
  1052.